﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using RWLib;
using Action = RWLib.Action;

namespace RWConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            var parser = new Parser();
            var text = "initially not dead and not loaded and alive\n" +
                       "Load releases loaded\n" +
                       "Shoot causes dead";          
            //var text = "initially not loadedR and not loadedL and not hidden and alive\n" +
            //            "Load_R causes loadedR\n" +
            //            "Load_L causes loadedL\n" +
            //            "Load_L releases alive if alive\n" +
            //            "Shoot_Fred_right causes not alive if not hidden and loadedR and alive\n" +
            //            "Shoot_Fred_left releases alive if (alive and not hidden and loadedL)\n" +
            //            "Sing causes hidden if not hidden\n" +
            //            "hidden triggers Wait\n" +
            //            "impossible Shoot_Fred_right at 4\n" +
            //            "Wait invokes Unhide after 3\n" +
            //            "Unhide causes not hidden if hidden";

            Console.WriteLine("---ERRORS---");
            parser.Parse(text);

            Console.WriteLine("\n\n---INITIAL FLUENTS---");
            foreach(var fluent in parser.InitialFluents)
                Console.WriteLine(fluent.Name + " " + fluent.Value);

            Console.WriteLine("\n\n---ACTIONS---");
            foreach (StatementBase action in parser.ActionFromTextList)
            {
                Console.WriteLine(action.Name);
                //impossible if
                if (action.ImpossibleCondition != null)
                    foreach (var clause in action.ImpossibleCondition.Conditions)
                    {
                        Console.WriteLine("Clause:");
                        foreach (var fluent in clause.Conditions)
                            Console.WriteLine("Fluent " + fluent.Name + ", negation " + fluent.Negation);
                    }
                //impossible at
                if (action.ImpossibleTimes != null)
                    Console.WriteLine("impossible at " + action.ImpossibleTimes.FirstOrDefault());
                //trigered by
                if (action.TriggeredBy != null)
                    Console.WriteLine("triggered by " + action.TriggeredBy.Name);
                if (action is ActionEffectStatement)
                    Console.WriteLine((ActionEffectStatement)action);
                if (action is FluentEffectStatement)
                    Console.WriteLine((FluentEffectStatement)action);
                if (action is ReleaseStatement)
                    Console.WriteLine((ReleaseStatement)action);
                if (action is TriggerStatement)
                    Console.WriteLine((TriggerStatement)action);
                Console.WriteLine("-------------------------------");
            }

            Console.WriteLine("\n\n---TREE---");
            SortedDictionary<int, List<string>> scenario = new SortedDictionary<int, List<string>>();
            //scenario.Add(1, new List<string>{"Load_R"});
            //scenario.Add(3, new List<string>{"Load_L"});
            //scenario.Add(5, new List<string>{"Shoot_Fred_right"});
            scenario.Add(1, new List<string> { "Load", "Shoot" });
            //scenario.Add(1, new List<string>{"Shoot"});
            Tree tree = parser.BuildTree(scenario);
            if (tree != null)
            {
                Console.WriteLine(tree);
                    Console.WriteLine("-------------------------------");
                    Console.WriteLine("\n\n---QUERIES---");
                    Console.WriteLine("always executable sc: " + parser.ParseQuery(tree, "always executable sc"));
                    Console.WriteLine("sometimes executable sc: " + parser.ParseQuery(tree, "sometimes executable sc"));
                    Console.WriteLine("alive always true at 3 during sc: " + parser.ParseQuery(tree, "alive always true at 3 during sc"));
                    Console.WriteLine("alive sometimes true at 3 during sc: " + parser.ParseQuery(tree, "alive sometimes true at 3 during sc"));
                    Console.WriteLine("not hidden always reachable after sc: " + parser.ParseQuery(tree, "not hidden always reachable after sc"));
                    Console.WriteLine("alive sometimes reachable after sc: " + parser.ParseQuery(tree, "alive sometimes reachable after sc"));
                    Console.WriteLine("Shoot executable during sc: " + parser.ParseQuery(tree, "Shoot executable during sc"));
            }
        }
    }
}
